#ifndef  FRAME_BUFFER_H
#define  FRAME_BUFFER_H

#include "Impl.h"

namespace frame {

class Buffer : public IReadBufferImpl, public IWriteBufferImpl {
public:
    typedef std::shared_ptr<Buffer> Ptr;
    enum {
        kBufferLength = 1024,
    };

	Buffer();
    ~Buffer() override;


    void * buffer() const override;
	size_t freeBytes() const override;

    const void * data() const override;
	size_t inBytes() const override;

	inline  void reset(){
		position = limit = 0;
	}
	inline size_t capacity() const {
		return cap;
	}

	// seek limit to next as put data in
	size_t fakePut(size_t bytes) override;
	size_t fakeGet(size_t bytes) override;
	void compact();

	int putBytes(const char * data, size_t len);
	int getBytes(char * data, size_t len);

	inline size_t TEST_position() const {
		return position;
	}
	inline size_t TEST_limit() const {
		return limit;
	}

    std::string toString() const ;
private:
	size_t position;
	size_t limit;
	size_t cap;
    char buf[kBufferLength];
};

class WriteBuffer : public IWriteBufferImpl {
public:
    WriteBuffer(const char * buf, size_t size)
    : buf(buf)
    , sz(size)
    {
    }
    WriteBuffer(const std::string & str)
    : buf(str.c_str())
    , sz(str.size())
    {
    }
    ~WriteBuffer() override {}

    const void * data() const override {
        return buf;
    }
    size_t inBytes() const override {
        return sz;
    }

private:
    const char * buf;
    size_t sz;
};

} // end of namespace frame

#endif   /* FRAME_BUFFER_H */
